import React, { useCallback, useRef, useState } from "react";
import { PriceFilterModuleProps } from "./type";
import InputAtom from "../../Atoms/Input.Atom";
import { InputAtomEnum } from "../../Atoms/Input.Atom/enum";

const PriceFilterModule: React.FC<PriceFilterModuleProps> = (props) => {
  const { minValue, maxValue, value, onChange } = props;
  const trackRef = useRef<HTMLDivElement>(null);
  const [isDraggingMin, setIsDraggingMin] = useState(false);
  const [isDraggingMax, setIsDraggingMax] = useState(false);

  const handleMinChange = useCallback(
    (newValue: number) => {
      const newMinValue = Math.max(minValue, Math.min(newValue, value[1]));
      onChange([newMinValue, value[1]]); // Вызовите onChange с новым значением диапазона цен
    },
    [value, onChange, minValue]
  );

  const handleMaxChange = useCallback(
    (newValue: number) => {
      const newMaxValue = Math.min(maxValue, Math.max(newValue, value[0]));
      onChange([value[0], newMaxValue]); // Вызовите onChange с новым значением диапазона цен
    },
    [value, onChange, maxValue]
  );

  const handleTrackClick = useCallback(
    (event: React.MouseEvent<HTMLDivElement>) => {
      const trackRect = trackRef.current?.getBoundingClientRect();
      if (trackRect) {
        const offsetX = event.clientX - trackRect.left;
        const ratio = offsetX / trackRect.width;
        const newValue = minValue + ratio * (maxValue - minValue);
        const closestValue =
          Math.abs(newValue - value[0]) < Math.abs(newValue - value[1])
            ? value[0]
            : value[1];
        if (closestValue === value[0]) {
          handleMinChange(newValue);
        } else {
          handleMaxChange(newValue);
        }
      }
    },
    [handleMinChange, handleMaxChange, maxValue, minValue, value]
  );

  const handleMouseDownMin = useCallback(() => {
    setIsDraggingMin(true);
  }, []);

  const handleMouseDownMax = useCallback(() => {
    setIsDraggingMax(true);
  }, []);

  const handleMouseMove = useCallback(
    (event: React.MouseEvent<HTMLDivElement>) => {
      if (isDraggingMin || isDraggingMax) {
        const trackRect = trackRef.current?.getBoundingClientRect();
        if (trackRect) {
          const offsetX = event.clientX - trackRect.left;
          const ratio = offsetX / trackRect.width;
          const newValue = minValue + ratio * (maxValue - minValue);
          if (isDraggingMin) {
            handleMinChange(newValue);
          } else {
            handleMaxChange(newValue);
          }
        }
      }
    },
    [
      isDraggingMin,
      isDraggingMax,
      handleMinChange,
      handleMaxChange,
      maxValue,
      minValue,
    ]
  );

  const handleMouseUp = useCallback(() => {
    setIsDraggingMin(false);
    setIsDraggingMax(false);
  }, []);

  const handleMouseLeave = useCallback(() => {
    setIsDraggingMin(false);
    setIsDraggingMax(false);
  }, []);

  return (
    <>
      <div
        className="relative flex gap-4 mx-4 items-center cursor-pointer"
        onMouseDown={handleTrackClick}
      >
        {/* Track */}
        <div
          ref={trackRef}
          className="flex w-full relative rounded-full bg-gray-600 border-x-transparent h-1 my-[calc((theme(spacing.6)-theme(spacing.3))/2)] data-[thumb-hidden=false]:border-x-[calc(theme(spacing.6)/2)]"
          onMouseMove={handleMouseMove}
          onMouseUp={handleMouseUp}
          onMouseLeave={handleMouseLeave}
        >
          {/* Selected range */}
          <div
            className="h-full absolute bg-tiffany"
            style={{
              width: `${
                ((value[1] - value[0]) / (maxValue - minValue)) * 100
              }%`,
              left: `${((value[0] - minValue) / (maxValue - minValue)) * 100}%`,
            }}
          />
          {/* Min range input */}
          <div
            className="bg-tiffany flex justify-center items-center before:absolute before:w-7 before:h-7 before:rounded-full after:shadow-small after:bg-background data-[focused=true]:z-10 outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 w-3 h-3 after:w-3 after:h-3 rounded-full after:rounded-full bg-primary top-1/2 cursor-pointer data-[dragging=true]:cursor-grabbing ring-transparent border-0 after:transition-all motion-reduce:after:transition-none data-[dragging=true]:after:scale-80 shadow-small"
            style={{
              left: `${((value[0] - minValue) / (maxValue - minValue)) * 100}%`,
              position: "absolute",
              transform: "translate(-50%,-50%)",
              touchAction: "none",
            }}
            onMouseDown={handleMouseDownMin}
          >
            <div className="p-1 bg-tiffany font-bold text-white text-h5 mb-12 rounded">
              {Math.round(value[0]).toLocaleString()}
            </div>
            <div
              style={{
                border: 0,
                clip: "rect(0px, 0px, 0px, 0px)",
                clipPath: "inset(50%)",
                height: "1px",
                width: "1px",
                padding: "0px",
                overflow: "hidden",
                translate: "(-50%,-50%)",
                position: "absolute",
                whiteSpace: "nowrap",
              }}
            >
              <InputAtom
                type={InputAtomEnum.RANGE}
                step={10}
                min={minValue}
                max={maxValue}
                value={Math.round(value[0])}
                onChange={handleMinChange}
              />
            </div>
          </div>
          {/* Max range input */}
          <div
            className="bg-tiffany flex justify-center items-center before:absolute before:w-7 before:h-7 before:rounded-full after:shadow-small after:bg-background data-[focused=true]:z-10 outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 w-3 h-3 after:w-3 after:h-3 rounded-full after:rounded-full bg-primary top-1/2 cursor-pointer data-[dragging=true]:cursor-grabbing ring-transparent border-0 after:transition-all motion-reduce:after:transition-none data-[dragging=true]:after:scale-80 shadow-small"
            style={{
              left: `${((value[1] - minValue) / (maxValue - minValue)) * 100}%`,
              position: "absolute",
              transform: "translate(-50%,-50%)",
              touchAction: "none",
            }}
            onMouseDown={handleMouseDownMax}
          >
            <div className="p-1 bg-tiffany font-bold text-white text-h5 mb-12 rounded">
              {Math.round(value[1]).toLocaleString()}
            </div>
            <div
              style={{
                border: 0,
                clip: "rect(0px, 0px, 0px, 0px)",
                clipPath: "inset(50%)",
                height: "1px",
                width: "1px",
                padding: "0px",
                overflow: "hidden",
                translate: "(-50%,-50%)",
                position: "absolute",
                whiteSpace: "nowrap",
              }}
            >
              <InputAtom
                type={InputAtomEnum.RANGE}
                step={10}
                min={minValue}
                max={maxValue}
                value={Math.round(value[1])}
                onChange={handleMaxChange}
              />
            </div>
          </div>
        </div>
      </div>
      <div className="flex justify-between">
        <div className="max-w-24">
          <InputAtom
            type={InputAtomEnum.NUMBER}
            value={Math.round(value[0])}
            onChange={handleMinChange}
            min={minValue}
            max={value[1]}
          />
        </div>
        <div className="max-w-24">
          <InputAtom
            type={InputAtomEnum.NUMBER}
            value={Math.round(value[1])}
            onChange={handleMaxChange}
            min={value[0]}
            max={maxValue}
          />
        </div>
      </div>
    </>
  );
};

export default React.memo(PriceFilterModule);
